﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Owin;

namespace Framework.Owin.RequestLog
{
    public class RequestLogMiddleware : OwinMiddleware
    {
        /// <summary>
        /// 下一个“中间件”对象
        /// </summary>
        OwinMiddleware _next;
        public RequestLogMiddleware(OwinMiddleware next, Action<string> requestLogProceAction)
            : base(next)
        {
            _next = next;
            //第一个参数是固定的，后边还可以添加自定义的其它参数
            _requestLogProceAction = requestLogProceAction;
        }
        /// <summary>
        /// 请求上下文处理
        /// </summary>
        public readonly Action<IOwinContext> RequestContextProceAction;
        /// <summary>
        /// 日志处理
        /// </summary>
        private readonly Action<string> _requestLogProceAction;
        public override Task Invoke(IOwinContext context)
        {
            if (RequestContextProceAction == null)
            {
                var stream = context.Request.Body;
                var byteTemp = new byte[1024];
                var body = "";
                while (true)
                {
                    var readCn = stream.Read(byteTemp, 0, 1024);
                    if (readCn <= 0)
                    {
                        break;
                    }
                    body += Encoding.UTF8.GetString(byteTemp, 0, readCn);
                }
                var sb = new StringBuilder();
                sb.AppendLine();
                sb.AppendFormat("[Headers]:{0}", context.Request.Headers.Aggregate("", (current, item) => current + string.Format("{0}:{1},", item.Key, string.Join(",", item.Value))));
                sb.AppendLine();
                sb.AppendFormat("[Host]:{0}", context.Request.Host);
                sb.AppendLine();
                sb.AppendFormat("[Method]:{0}", context.Request.Method);
                sb.AppendLine();
                sb.AppendFormat("[URL]:{0}", context.Request.Uri);
                sb.AppendLine();
                sb.AppendFormat("[Parameter]:{0}", body);
                sb.AppendLine();
                _requestLogProceAction(sb.ToString());
            }
            else
            {
                RequestContextProceAction(context);
            }
            return _next.Invoke(context);
        }
    }
}
